/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.rational.sheet.table;

import java.util.HashSet;
import java.util.TreeMap;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import org.rational.sheet.table.cell.model.CellAddress;
import org.rational.sheet.table.cell.model.Cell;
import org.rational.sheet.table.cell.model.CellAddressComparator;
import org.rational.sheet.table.cell.model.CellValue;

/**
 *
 * @author Overmind
 */
public class RationalTableData
    implements TableData
{
    private TreeMap<CellAddress, Cell> cells;
    private int height;
    private int width;
    
    private RationalParser parser;
    
    private HashSet<TableModelListener> tableModelListeners = new HashSet<>();
    
    {
        cells = new TreeMap<>(new CellAddressComparator());
    }
    
    public RationalTableData(int height, int width)
    {
        this.height = height;
        this.width = width;
        
        parser = new RationalParser(this);
    }

    @Override
    public int getRowCount()
    {
        return height;
    }

    @Override
    public int getColumnCount()
    {
        return width;
    }
    
    @Override
    public String getColumnName(int column) 
    {
        return CellAddress.getColumnName(column);
    }

    @Override
     public Class<?> getColumnClass(int column)
    {
        return CellValue.class;
    }
    
    @Override
    public Cell getCellAt(CellAddress address)
    {
	Cell cell = cells.get(address);
        
        if(cell == null)
	{
	    cell = new Cell(parser);
	    cells.put(address, cell);
	}
	
	return cell;
    }
    
    @Override
    public Object getValueAt(int row, int column)
    {
        return getValueAt(new CellAddress(row, column));
    }
    
    @Override
    public String getValueAt(CellAddress address) 
    {
	return getCellAt(address).getValue();
    }

    @Override
    public boolean isCellEditable(int row, int column)
    {
        return true;
    }
    
    @Override
    public void setValueAt(String string, CellAddress address)
    {
	Cell cell = cells.get(address);
        
        if(cell == null)
	{
	    cell = new Cell(parser);
	    cells.put(address, cell);
	}
	
	cell.setFormula(string);
    }

    @Override
    public void setValueAt(Object object, int row, int column)
    {
        setValueAt((String)object, new CellAddress(row, column));
        fireTableChanged(new TableModelEvent(this, row, row, column));
    }
    
    public void fireTableChanged(TableModelEvent event)
    {
        for(TableModelListener listener : tableModelListeners)
        {
            listener.tableChanged(event);
        }
    }
    
    @Override
    public void addTableModelListener(TableModelListener listener)
    {
        tableModelListeners.add(listener);
    }
    
    @Override
    public void removeTableModelListener(TableModelListener listener)
    {
        tableModelListeners.remove(listener);
    }

}
